﻿using PrinterMonitorSvc.Ext;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Printing;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace PrinterMonitorSvc.Common
{
    /// <summary>
    /// 打印帮助类(需要引入PdfiumViewer.dll(有修改)和PdfiumViewer.Native.x86.no_v8-no_xfa包(NUGET))
    /// </summary>
    public static class PrinterHelper
    {
        private static Image _img = null;

        #region 设置为默认打印机
        /// <summary>
        /// 设置为默认打印机
        /// </summary>
        /// <param name="Name"></param>
        /// <returns></returns>
        [DllImport("winspool.drv")]
        public static extern bool SetDefaultPrinter(string Name);
        #endregion

        #region 获取本机默认打印机名称
        /// <summary>  
        /// 获取本机默认打印机名称  
        /// </summary>  
        public static string DefaultPrinter
        {
            get
            {
                using (PrintDocument printDocument = new PrintDocument())
                {
                    return printDocument.PrinterSettings.PrinterName;
                }
            }
        }
        #endregion

        #region 获取所有可用的打印机名称
        /// <summary>
        /// 获取所有可用的打印机名称
        /// </summary>
        /// <returns>打印机名称列表</returns>
        public static IEnumerable<string> GetAllPrinters()
        {
            List<string> printers = new List<string>();
            var source = PrinterSettings.InstalledPrinters;
            if (source.Count > 0)
            {
                foreach (string printer in source)
                {
                    printers.Add(printer);
                }
            }

            return printers.OrderBy(s => s).Distinct().ToList();
        }
        #endregion

        #region CMD命令打印
        /// <summary>
        /// CMD命令打印
        /// </summary>
        /// <param name="filename">文件物理路径</param>
        /// <param name="printerName">打印机名称</param>
        /// <param name="milliseconds">超时时间(毫秒),默认无限期等待</param>
        public static void Print(string filename, string printerName, int milliseconds = -1)
        {
            try
            {
                using (PrintDocument document = new PrintDocument())
                using (Process process = new Process())
                {
                    document.DefaultPageSettings.PrinterSettings.PrinterName = printerName;
                    ProcessStartInfo startInfo = new ProcessStartInfo();
                    var foxitExe = WinHelper.GetSoftWareInstallPos("Foxit Reader", "FoxitReader.exe");
                    if (foxitExe.IsEmpty())
                    {
                        startInfo.FileName = filename;
                        startInfo.Verb = "PrintTo";
                        //可以防止打印机名称空格
                        startInfo.Arguments = "\"" + printerName + "\"";
                    }
                    else
                    {
                        startInfo.FileName = foxitExe;
                        startInfo.Arguments = "/t \"" + filename + "\" \"" + printerName + "\"";
                    }
                    startInfo.CreateNoWindow = true;
                    startInfo.WindowStyle = ProcessWindowStyle.Hidden;
                    startInfo.UseShellExecute = true;
                    process.StartInfo = startInfo;
                    process.Start();
                    process.WaitForExit(milliseconds);
                }
            }
            catch (Exception ex)
            {
                throw new Exception("请安装福昕阅读器(FoxitReader)进行打印，下载地址：【https://www.foxitsoftware.cn/pdf-reader/】", ex);
            }
        }
        #endregion

        #region 打印图片
        /// <summary>
        /// 打印图片文件
        /// </summary>
        /// <param name="url">请求地址</param>
        /// <param name="printerName">打印机名称(默认为当前系统打印机)</param>
        public static void PrintImageUrl(string url, string printerName = null)
        {
            var content = FileHelper.DownloadData(url);
            PrintImage(content, printerName);
        }
        /// <summary>
        /// 打印字节文件
        /// </summary>
        /// <param name="fileContent">文件字节内容</param>
        /// <param name="printerName">打印机名称(默认为当前系统打印机)</param>
        public static void PrintImage(byte[] fileContent, string printerName = null)
        {
            using (var stream = new MemoryStream(fileContent))
            {
                PrintImage(stream, printerName);
            }
        }

        /// <summary>
        /// 打印流文件
        /// </summary>
        /// <param name="fileStream">文件流</param>
        /// <param name="printerName">打印机名称(默认为当前系统打印机)</param>
        public static void PrintImage(Stream fileStream, string printerName = null)
        {
            using (var printDocument = new PrintDocument())
            {
                _img = Image.FromStream(fileStream);
                printDocument.PrintPage += Document_PrintPage;

                // 设置要使用的打印机
                if (!string.IsNullOrWhiteSpace(printerName))
                {
                    printDocument.PrinterSettings.PrinterName = printerName;
                }

                // 隐藏打印进度弹窗
                printDocument.PrintController = new StandardPrintController();

                printDocument.Print();
                printDocument.PrintPage -= Document_PrintPage;
                printDocument.Dispose();
                _img.Dispose();
                _img = null;
            }
        }

        private static void Document_PrintPage(object sender, PrintPageEventArgs e)
        {
            e.Graphics.DrawImage(_img, e.PageBounds);
        }
        #endregion
    }
}
